From 67e0d840e74f7a40087a0a4436ce6ecdd3811044 Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Fri, 9 Jul 2004 10:38:33 +0000 Subject: [PATCH] bitkeeper revision 1.1053.1.1 (40ee75a9YghVZFFolzFjyJngpxAbKg) Move to new model of network and vif control using shell scripts. --- .rootkeys | 3 + tools/examples/Makefile | 34 ++--- tools/examples/network | 165 ++++++++++++++++++++++ tools/examples/vif-bridge | 85 +++++++++++ tools/examples/vifctl | 4 +- tools/examples/xend-config.sxp | 23 +++ tools/examples/xmdefaults | 2 +- tools/examples/xmnetbsd | 2 +- tools/misc/netfix | 5 +- tools/python/xen/util/ip.py | 2 +- tools/python/xen/xend/Vifctl.py | 84 +++++++---- tools/python/xen/xend/XendDomainInfo.py | 33 ++--- tools/python/xen/xend/XendRoot.py | 41 +++++- tools/python/xen/xend/server/SrvDaemon.py | 5 +- tools/python/xen/xend/server/SrvServer.py | 11 +- tools/python/xen/xend/server/netif.py | 97 ++++++------- tools/python/xen/xm/create.py | 32 ++++- 17 files changed, 486 insertions(+), 142 deletions(-) create mode 100755 tools/examples/network create mode 100755 tools/examples/vif-bridge create mode 100644 tools/examples/xend-config.sxp diff --git a/.rootkeys b/.rootkeys index f953e63aea..a34d19ce07 100644 --- a/.rootkeys +++ b/.rootkeys @@ -156,7 +156,10 @@ 401d7e160vaxMBAUSLSicuZ7AQjJ3w tools/examples/Makefile 401d7e16UgeqroJQTIhwkrDVkoWgZQ tools/examples/README 405ff55dawQyCHFEnJ067ChPRoXBBA tools/examples/init.d/xend +40ee75a9xFz6S05sDKu-JCLqyVTkDA tools/examples/network +40ee75a967sxgcRY4Q7zXoVUaJ4flA tools/examples/vif-bridge 40e15b7edWEtBf_oe3eBwGKuh1dyzQ tools/examples/vifctl +40ee75a93cqxHp6MiYXxxwR5j2_8QQ tools/examples/xend-config.sxp 40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmdefaults 40dfd40auJwNnb8NoiSnRkvZaaXkUg tools/examples/xmnetbsd 3fbba6dbDfYvJSsw9500b4SZyUhxjQ tools/libxc/Makefile diff --git a/tools/examples/Makefile b/tools/examples/Makefile index 4df04eed55..f7c3fd7420 100644 --- a/tools/examples/Makefile +++ b/tools/examples/Makefile @@ -1,35 +1,35 @@ INSTALL = $(wildcard *.py) -ETC = xmdefaults -ETCDIR = /etc/xen - INITD = init.d/xend -XEND = vifctl -XEND_DIR = $(ETCDIR)/xend +XEN_CONFIG_DIR = /etc/xen +XEN_CONFIGS = xmdefaults xmnetbsd xend-config.sxp + +XEN_SCRIPT_DIR = /etc/xen +XEN_SCRIPTS = vifctl network vif-bridge all: -install: all install-initd install-etc install-xend +install: all install-initd install-configs install-scripts install-initd: mkdir -p $(prefix)/etc/init.d install -m0755 $(INITD) $(prefix)/etc/init.d -install-etc: - mkdir -p $(prefix)$(ETCDIR) - mkdir -p $(prefix)$(ETCDIR)/auto - for i in $(ETC); \ - do [ -a $(prefix)/$(ETCDIR)/$$i ] || \ - install -m0644 $$i $(prefix)$(ETCDIR); \ +install-configs: + mkdir -p $(prefix)$(XEN_CONFIG_DIR) + mkdir -p $(prefix)$(XEN_CONFIG_DIR)/auto + for i in $(XEN_CONFIGS); \ + do [ -a $(prefix)/$(XEN_CONFIG_DIR)/$$i ] || \ + install -m0644 $$i $(prefix)$(XEN_CONFIG_DIR); \ done -install-xend: - mkdir -p $(prefix)$(XEND_DIR) - for i in $(XEND); \ - do [ -a $(prefix)/$(XEND_DIR)/$$i ] || \ - install -m0755 $$i $(prefix)$(XEND_DIR); \ +install-scripts: + mkdir -p $(prefix)$(XEN_SCRIPT_DIR) + for i in $(XEN_SCRIPTS); \ + do [ -a $(prefix)/$()/$$i ] || \ + install -m0755 $$i $(prefix)$(XEN_SCRIPT_DIR); \ done clean: diff --git a/tools/examples/network b/tools/examples/network new file mode 100755 index 0000000000..49ce29da0a --- /dev/null +++ b/tools/examples/network @@ -0,0 +1,165 @@ +#!/bin/sh +#============================================================================ +# Example Xen network start/stop script. +# Xend calls a network script when it starts. +# This is the default script. +# +# /etc/xen/network (start|stop|status) {VAR=VAL}* +# +# Vars: +# +# bridge The bridge to use (default xen-br0). +# netdev The interface to add to the bridge (default eth0). +# antispoof Whether to use iptables to prevent spoofing (default yes). +# +# start: +# Creates the bridge and enslaves netdev to it. +# Copies the IP addresses from netdev to the bridge. +# Deletes the routes to netdev and adds them on bridge. +# +# stop: +# Removes netdev from the bridge. +# Deletes the routes to bridge and adds them to netdev. +# +# status: +# Print ifconfig for netdev and bridge. +# Print routes. +# +#============================================================================ + +# Exit if anything goes wrong. +set -e + +# First arg is the operation. +OP=$1 +shift + +# Pull variables in args in to environment. +for arg ; do export "${arg}" ; done + +bridge=${bridge:-xen-br0} +netdev=${netdev:-eth0} +antispoof=${antispoof:-yes} + +echo "network $OP bridge=$bridge netdev=$netdev antispoof=$antispoof" + +# Usage: transfer_addrs src dst +# Copy all IP addresses (including aliases) from device $src to device $dst. +transfer_addrs () { + local src=$1 + local dst=$2 + # Don't bother if $dst already has IP addresses. + if ip addr show dev ${dst} | egrep -q '^ *inet' ; then + return + fi + # Address lines start with 'inet' and have the device in them. + # Replace 'inet' with 'ip addr add' and change the device name $src + # to 'dev $src'. + ip addr show dev ${src} | egrep '^ *inet' | sed -e " +s/inet/ip addr add/ +s/${src}/dev ${dst}/ +" | sh -e +} + +# Usage: transfer_routes src dst +# Get all IP routes to device $src, delete them, and +# add the same routes to device $dst. +# The original routes have to be deleted, otherwise adding them +# for $dst fails (duplicate routes). +transfer_routes () { + local src=$1 + local dst=$2 + # List all routes and grep the ones with $src in. + # Stick 'ip route del' on the front to delete. + # Change $src to $dst and use 'ip route add' to add. + ip route list | grep ${src} | sed -e " +h +s/^/ip route del / +P +g +s/${src}/${dst}/ +s/^/ip route add / +P +d +" | sh -e +} + +# Usage: create_bridge dev bridge +# Create bridge $bridge and add device $dev to it. +create_bridge () { + local dev=$1 + local bridge=$2 + + # Don't create the bridge if it already exists. + if ! brctl show | grep -q ${bridge} ; then + brctl addbr ${bridge} + brctl stp ${bridge} off + brctl setfd ${bridge} 0 + brctl sethello ${bridge} 0 + fi + ifconfig ${bridge} up + # Don't add $dev to $bridge if it's already on a bridge. + if ! brctl show | grep -q ${dev} ; then + brctl addif ${bridge} ${dev} + fi +} + +# Usage: antispoofing dev bridge +# Set the default forwarding policy for $dev to drop. +# Allow forwarding to the bridge. +antispoofing () { + local dev=$1 + local bridge=$2 + + iptables -P FORWARD DROP + iptables -A FORWARD -m physdev --physdev-in ${dev} -j ACCEPT +} + +# Usage: show_status dev bridge +# Print ifconfig and routes. +show_status () { + local dev=$1 + local bridge=$2 + + echo '============================================================' + ifconfig ${dev} + ifconfig ${bridge} + echo ' ' + ip route list + echo ' ' + route -n + echo '============================================================' +} + +case ${OP} in + start) + # Create the bridge and give it the interface IP addresses. + # Move the interface routes onto the bridge. + create_bridge ${netdev} ${bridge} + transfer_addrs ${netdev} ${bridge} + transfer_routes ${netdev} ${bridge} + + if [ ${antispoof} == 'yes' ] ; then + antispoofing ${netdev} ${bridge} + fi + + ;; + + stop) + # Remove the interface from the bridge. + # Move the routes back to the interface. + brctl delif ${bridge} ${netdev} + transfer_routes ${bridge} ${netdev} + + # It's not our place to be enabling forwarding... + ;; + + status) + show_status ${netdev} ${bridge} + ;; + + *) + echo 'Unknown command: ' ${OP} + echo 'Valid commands are: start, stop, status' + exit 1 +esac diff --git a/tools/examples/vif-bridge b/tools/examples/vif-bridge new file mode 100755 index 0000000000..2138aa7b94 --- /dev/null +++ b/tools/examples/vif-bridge @@ -0,0 +1,85 @@ +#!/bin/sh +#============================================================================ +# /etc/xen/vif-bridge +# +# Script for configuring a vif in bridged mode. +# Xend calls a vif script when bringing a vif up or down. +# This script is the default - but it can be configured for each vif. +# +# Example invocation: +# +# vif-bridge up domain=VM1 vif=vif1.0 bridge=xen-br0 ip="128.232.38.45/28 10.10.10.55/24" +# +# +# Usage: +# vif-bridge (up|down) {VAR=VAL}* +# +# Vars: +# +# domain name of the domain the interface is on (required). +# vif vif interface name (required). +# mac vif MAC address (required). +# bridge bridge to add the vif to (required). +# ip list of IP networks for the vif, space-separated (optional). +# +# up: +# Enslaves the vif interface to the bridge and adds iptables rules +# for its ip addresses (if any). +# +# down: +# Removes the vif interface from the bridge and removes the iptables +# rules for its ip addresses (if any). +#============================================================================ + +# Exit if anything goes wrong +set -e + +echo "vif-bridge $*" + +# Operation name. +OP=$1 +shift + +# Pull variables in args into environment +for arg ; do export "${arg}" ; done + +# Required parameters. Fail if not set. +domain=${domain:?} +vif=${vif:?} +mac=${mac:?} +bridge=${bridge:?} + +# Optional parameters. Set defaults. +ip=${ip:-''} # default to null (do nothing) + +# Are we going up or down? +case $OP in + up) + brcmd='addif' + iptcmd='-A' + ;; + down) + brcmd='delif' + iptcmd='-D' + ;; + *) + echo 'Invalid command: ' $OP + echo 'Valid commands are: up, down' + exit 1 + ;; +esac + +# Add/remove vif to/from bridge. +brctl ${brcmd} ${bridge} ${vif} + +if [ ${ip} ] ; then + + # If we've been given a list of IP networks, allow pkts with these src addrs. + for addr in ${ip} ; do + iptables ${iptcmd} FORWARD -m physdev --physdev-in ${vif} -s ${addr} -j ACCEPT + done + + # Always allow us to talk to a DHCP server anyhow. + iptables ${iptcmd} FORWARD -m physdev --physdev-in ${vif} -p udp --sport 68 --dport 67 -j ACCEPT +fi + diff --git a/tools/examples/vifctl b/tools/examples/vifctl index 3ed0d90623..11aac70fa2 100644 --- a/tools/examples/vifctl +++ b/tools/examples/vifctl @@ -16,7 +16,7 @@ # added on up and removed on down. The bridge a vif is added to can # be set in the vm config. # -# The default bridge is nbe-br. +# The default bridge is xen-br0. # The default interface is eth0. # #============================================================================ @@ -33,7 +33,7 @@ class VifControl: prefix = 'vifctl_' - DEFAULT_BRIDGE = 'nbe-br' + DEFAULT_BRIDGE = 'xen-br0' DEFAULT_INTERFACE = 'eth0' def __init__(self): diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp new file mode 100644 index 0000000000..f710a54529 --- /dev/null +++ b/tools/examples/xend-config.sxp @@ -0,0 +1,23 @@ +# Xend configuration file. + +# Port xend should use for the HTTP interface. +(xend-port 8000) + +# Address xend should listen on. +# Specifying 'localhost' prevents remote connections. +# Specifying the empty string '' allows all connections. +(xend-address '') + +# The script used to start/stop networking for xend. +(network-script network) + +# The default bridge that virtual interfaces should be connected to. +(vif-bridge xen-br0) + +# The default script used to control virtual interfaces. +(vif-script vif-bridge) + +# Whether iptables should be set up to prevent IP spoofing for +# virtual interfaces. Specify 'yes' or 'no'. +(vif-antispoof no) + diff --git a/tools/examples/xmdefaults b/tools/examples/xmdefaults index 640a7390a0..2c417a7cf8 100644 --- a/tools/examples/xmdefaults +++ b/tools/examples/xmdefaults @@ -49,7 +49,7 @@ cpu = vmid # set based on vmid (mod number of CPUs) # Optionally define mac and/or bridge for the network interfaces. # Random MACs are assigned if not given. -#vif = [ 'mac=aa:00:00:00:00:11, bridge=nbe-br' ] +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ] #---------------------------------------------------------------------------- # Define the disk devices you want the domain to have access to, and diff --git a/tools/examples/xmnetbsd b/tools/examples/xmnetbsd index 4f920087b6..e62de6174e 100644 --- a/tools/examples/xmnetbsd +++ b/tools/examples/xmnetbsd @@ -41,7 +41,7 @@ name = "NetBSD VM %d" % vmid # Optionally define mac and/or bridge for the network interfaces. # Random MACs are assigned if not given. -#vif = [ 'mac=aa:00:00:00:00:11, bridge=nbe-br' ] +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ] # Specify IP address(es), for the new domain. You need to # configure IP addrs within the domain just as you do normally. This diff --git a/tools/misc/netfix b/tools/misc/netfix index df38e438a1..429f579c02 100644 --- a/tools/misc/netfix +++ b/tools/misc/netfix @@ -3,7 +3,7 @@ #============================================================================ # Copyright (C) 2004 Mike Wray #============================================================================ -# Move the IP address from eth0 onto the Xen bridge (nbe-br). +# Move the IP address from eth0 onto the Xen bridge (xen-br0). # Only works if the bridge control utils (brctl) have been installed. #============================================================================ @@ -14,6 +14,9 @@ short_options = 'hvqni:b:c' long_options = ['help', 'verbose', 'quiet', 'interface=', 'bridge=', 'create'] +defaults['interface'] = 'eth0' +defaults['bridge'] = 'xen-br0' + def usage(): print """Usage: %s [options] diff --git a/tools/python/xen/util/ip.py b/tools/python/xen/util/ip.py index 39eb01f944..8f93687139 100644 --- a/tools/python/xen/util/ip.py +++ b/tools/python/xen/util/ip.py @@ -39,7 +39,7 @@ def _readline(fd): When bridging is used, eth0 may not have an IP address, as it may have been moved onto the bridge. """ -NBE_BRIDGE = 'nbe-br' +NBE_BRIDGE = 'xen-br0' def get_current_ipaddr(dev='eth0'): """Get the primary IP address for the given network interface. diff --git a/tools/python/xen/xend/Vifctl.py b/tools/python/xen/xend/Vifctl.py index 884ed9677d..86f68db0b4 100644 --- a/tools/python/xen/xend/Vifctl.py +++ b/tools/python/xen/xend/Vifctl.py @@ -1,36 +1,70 @@ -"""Xend interface to the vifctl script. +"""Xend interface to networking control scripts. """ import os import os.path import sys -VIFCTL = '/etc/xen/xend/vifctl' +from xen.xend import XendRoot +xroot = XendRoot.instance() -def init(): - """Call 'vifctl init'. Called when xend starts. +"""Where network control scripts live.""" +SCRIPT_DIR = xroot.network_script_dir + +def network(op, script=None, bridge=None, antispoof=None): + """Call a network control script. + Xend calls this with op 'start' when it starts. + + @param op: operation (start, stop, status) + @param script: network script name + @param bridge: xen bridge + @param antispoof: whether to enable IP antispoofing rules """ - os.system(VIFCTL + ' init ') + if op not in ['start', 'stop', 'status']: + raise ValueError('Invalid operation:' + op) + if script is None: + script = xroot.get_network_script() + if bridge is None: + bridge = xroot.get_vif_bridge() + if antispoof is None: + antispoof = xroot.get_vif_antispoof() + script = os.path.join(SCRIPT_DIR, script) + args = [op] + args.append("bridge='%s'" % bridge) + if antispoof: + args.append("antispoof=yes") + else: + args.append("antispoof=no") + args = ' '.join(args) + os.system(script + ' ' + args) + +def vifctl(op, vif=None, script=None, domain=None, mac=None, bridge=None, ipaddr=[]): + """Call a vif control script. + Xend calls this when bringing vifs up or down. -def vifctl_args(vif, mac=None, bridge=None, ipaddr=[]): - """Construct the argument list for vifctl. + @param op: vif operation (up, down) + @param vif: vif name + @param script: name of control script + @param domain: name of domain the vif is on + @param mac: vif MAC address + @param bridge: bridge to add the vif to + @param ipaddr: list of ipaddrs the vif may use """ - args = ['vif=%s' % vif] - if mac: - args.append('mac=%s' % mac) + if op not in ['up', 'down']: + raise ValueError('Invalid operation:' + op) + if script is None: + script = xroot.get_vif_script() + if bridge is None: + bridge = xroot.get_vif_bridge() + script = os.path.join(SCRIPT_DIR, script) + args = [op] + args.append("vif='%s'" % vif) + args.append("domain='%s'" % domain) + args.append("mac='%s'" % mac) if bridge: - args.append('bridge=%s' % bridge) - for ip in ipaddr: - args.append('ipaddr=%s' % ip) - return ' '.join(args) - -def up(vif, **kwds): - """Call 'vifctl up' for a vif. Called when a vif is created. - """ - args = vifctl_args(vif, **kwds) - os.system(VIFCTL + ' up ' + args) + args.append("bridge='%s'" % bridge) + if ipaddr: + ips = ' '.join(ipaddr) + args.append("ip='%s'" % ips) + args = ' '.join(args) + os.system(script + ' ' + args) -def down(vif, **kwds): - """Call 'vifctl down' for a vif. Called when a vif is destroyed. - """ - args = vifctl_args(vif, **kwds) - os.system(VIFCTL + ' down ' + args) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 5dff09e388..89c1731fbc 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -146,16 +146,6 @@ def make_disk(dom, uname, dev, mode, recreate=0): ctrl.addCallback(fn) return ctrl -def make_vif(dom, vif, vmac, recreate=0): - """Create a virtual network device for a domain. - - - @returns Deferred - """ - xend.netif_create(dom, recreate=recreate) - d = xend.netif_dev_create(dom, vif, vmac, recreate=recreate) - return d - def vif_up(iplist): """send an unsolicited ARP reply for all non link-local IP addresses. @@ -312,28 +302,28 @@ def append_deferred(dlist, v): def _vm_configure1(val, vm): d = vm.create_devices() - print '_vm_configure1> made devices...' + #print '_vm_configure1> made devices...' def cbok(x): - print '_vm_configure1> cbok', x + #print '_vm_configure1> cbok', x return x d.addCallback(cbok) d.addCallback(_vm_configure2, vm) - print '_vm_configure1<' + #print '_vm_configure1<' return d def _vm_configure2(val, vm): - print '>callback _vm_configure2...' + #print '>callback _vm_configure2...' d = vm.configure_fields() def cbok(results): - print '_vm_configure2> cbok', results + #print '_vm_configure2> cbok', results return vm def cberr(err): - print '_vm_configure2> cberr', err + #print '_vm_configure2> cberr', err vm.destroy() return err d.addCallback(cbok) d.addErrback(cberr) - print '<_vm_configure2' + #print '<_vm_configure2' return d class XendDomainInfo: @@ -803,14 +793,11 @@ def vm_dev_vif(vm, val, index): raise VmError('vif: vif in netif backend domain') vif = index #todo vmac = sxp.child_value(val, "mac") - defer = make_vif(vm.dom, vif, vmac, vm.recreate) + xend.netif_create(vm.dom, recreate=vm.recreate) + defer = xend.netif_dev_create(vm.dom, vif, val, recreate=vm.recreate) def fn(id): dev = xend.netif_dev(vm.dom, vif) - devid = sxp.attribute(val, 'id') - if devid: - dev.setprop('id', devid) - bridge = sxp.child_value(val, "bridge") - dev.up(bridge) + dev.vifctl('up') vm.add_device('vif', dev) print 'vm_dev_vif> created', dev return id diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index 665f5df29e..f022389695 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -41,6 +41,9 @@ class XendRoot: """Environment variable used to override config_default.""" config_var = "XEND_CONFIG" + """Where network control scripts live.""" + network_script_dir = "/etc/xen" + def __init__(self): self.rebooted = 0 self.last_reboot = None @@ -99,6 +102,7 @@ class XendRoot: return self.rebooted def configure(self): + print 'XendRoot>configure>' self.set_config() self.dbroot = self.get_config_value("dbroot", self.dbroot_default) self.lastboot = self.get_config_value("lastboot", self.lastboot_default) @@ -114,23 +118,27 @@ class XendRoot: The config file is a sequence of sxp forms. """ self.config_path = os.getenv(self.config_var, self.config_default) + print 'XendRoot>set_config> config_path=', self.config_path if os.path.exists(self.config_path): + print 'XendRoot>set_config> loading' fin = file(self.config_path, 'rb') try: config = sxp.parse(fin) - config.insert(0, 'config') + config.insert(0, 'xend-config') self.config = config finally: fin.close() else: - self.config = ['config'] + print 'XendRoot>set_config> not found' + self.config = ['xend-config'] + print 'XendRoot> config=', self.config def get_config(self, name=None): """Get the configuration element with the given name, or the whole configuration if no name is given. - name element name (optional) - returns config or none + @param name: element name (optional) + @return: config or none """ if name is None: val = self.config @@ -141,12 +149,31 @@ class XendRoot: def get_config_value(self, name, val=None): """Get the value of an atomic configuration element. - name element name - val default value (optional, defaults to None) - returns value + @param name: element name + @param val: default value (optional, defaults to None) + @return: value """ return sxp.child_value(self.config, name, val=val) + def get_xend_port(self): + return int(self.get_config_value('xend-port', '8000')) + + def get_xend_address(self): + return self.get_config_value('xend-address', '') + + def get_network_script(self): + return self.get_config_value('network-script', 'network') + + def get_vif_bridge(self): + return self.get_config_value('vif-bridge', 'xen-br0') + + def get_vif_script(self): + return self.get_config_value('vif-script', 'vif-bridge') + + def get_vif_antispoof(self): + v = self.get_config_value('vif-antispoof', 'yes') + return v in ['yes', '1', 'on'] + def instance(): global inst try: diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index c4e562e711..e80b23334e 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -734,15 +734,14 @@ class Daemon: def netif_get(self, dom): return self.netifCF.getInstanceByDom(dom) - def netif_dev_create(self, dom, vif, vmac, recreate=0): + def netif_dev_create(self, dom, vif, config, recreate=0): """Create a network device. - todo """ ctrl = self.netifCF.getInstanceByDom(dom) if not ctrl: raise ValueError('No netif controller: %d' % dom) - d = ctrl.attachDevice(vif, vmac, recreate=recreate) + d = ctrl.attachDevice(vif, config, recreate=recreate) return d def netif_dev(self, dom, vif): diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py index ac201dd10d..9bc42f4217 100644 --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -37,19 +37,18 @@ from xen.xend import Vifctl from SrvRoot import SrvRoot def create(port=None, interface=None, bridge=0): - if port is None: port = 8000 - if interface is None: interface = '' + if port is None: + port = xroot.get_xend_port() + if interface is None: + interface = xroot.get_xend_address() if bridge or xroot.rebooted: - init_bridge() + Vifctl.network('start') root = resource.Resource() xend = SrvRoot() root.putChild('xend', xend) site = server.Site(root) reactor.listenTCP(port, site, interface=interface) -def init_bridge(): - Vifctl.init() - def main(port=None, interface=None): create(port, interface) reactor.run() diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py index 415ab2409b..4d3b854bed 100755 --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -109,20 +109,42 @@ class NetDev(controller.Dev): """Info record for a network device. """ - def __init__(self, ctrl, vif, mac): + def __init__(self, ctrl, vif, config): controller.Dev.__init__(self, ctrl) self.vif = vif - self.mac = mac self.evtchn = None + self.configure(config) + + def configure(self, config): + self.config = config + self.mac = None self.bridge = None - self.ipaddr = [] + self.script = None + self.ipaddr = None + + vmac = sxp.child_value(config, 'mac') + if not vmac: raise ValueError("invalid mac") + mac = [ int(x, 16) for x in vmac.split(':') ] + if len(mac) != 6: raise ValueError("invalid mac") + self.mac = mac + self.bridge = sxp.child_value(config, 'bridge') + self.script = sxp.child_value(config, 'script') + + ipaddrs = sxp.children(config, elt='ip') + for ipaddr in ipaddrs: + self.ipaddr.append(sxp.child0(ipaddr)) + def sxpr(self): vif = str(self.vif) mac = self.get_mac() - val = ['netdev', ['vif', vif], ['mac', mac]] + val = ['vif', ['idx', vif], ['mac', mac]] if self.bridge: val.append(['bridge', self.bridge]) + if self.script: + val.append(['script', self.script]) + for ip in self.ipaddr: + val.append(['ip', ip]) if self.evtchn: val.append(['evtchn', self.evtchn['port1'], @@ -140,24 +162,22 @@ class NetDev(controller.Dev): return ':'.join(map(lambda x: "%x" % x, self.mac)) def vifctl_params(self): - return { 'mac' : self.get_mac(), + from xen.xend import XendDomain + xd = XendDomain.instance() + dom = self.controller.dom + dominfo = xd.domain_get(dom) + name = (dominfo and dominfo.name) or ('DOM%d' % dom) + return { 'domain': name, + 'vif' : self.get_vifname(), + 'mac' : self.get_mac(), 'bridge': self.bridge, - 'ipaddr': self.ipaddr } + 'script': self.script, + 'ipaddr': self.ipaddr, } - def up(self, bridge=None, ipaddr=[]): - """Bring the device up. - - bridge ethernet bridge to connect to - ipaddr list of ipaddrs to filter using iptables + def vifctl(self, op): + """Bring the device up or down. """ - self.bridge = bridge - self.ipaddr = ipaddr - Vifctl.up(self.get_vifname(), **self.vifctl_params()) - - def down(self): - """Bring the device down. - """ - Vifctl.down(self.get_vifname(), **self.vifctl_params()) + Vifctl.vifctl(op, **self.vifctl_params()) def destroy(self): """Destroy the device's resources and disconnect from the back-end @@ -165,7 +185,7 @@ class NetDev(controller.Dev): """ def cb_destroy(val): self.controller.send_be_destroy(self.vif) - self.down() + self.vifctl('down') #d = self.controller.factory.addDeferred() d = defer.Deferred() d.addCallback(cb_destroy) @@ -194,24 +214,6 @@ class NetifController(controller.Controller): val = ['netif', ['dom', self.dom]] return val - def randomMAC(self): - """Generate a random MAC address. - - Uses OUI (Organizationally Unique Identifier) AA:00:00, an - unassigned one that used to belong to DEC. The OUI list is - available at 'standards.ieee.org'. - - The remaining 3 fields are random, with the first bit of the first - random field set 0. - - returns array of 6 ints - """ - mac = [ 0xaa, 0x00, 0x00, - random.randint(0x00, 0x7f), - random.randint(0x00, 0xff), - random.randint(0x00, 0xff) ] - return mac - def lostChannel(self): """Method called when the channel has been lost. """ @@ -231,22 +233,15 @@ class NetifController(controller.Controller): """ return self.devices.get(vif) - def addDevice(self, vif, vmac): - """Add a network interface. If vmac is None a random MAC is - assigned. If specified, vmac must be a string of the form - XX:XX:XX:XX:XX where X is hex digit. + def addDevice(self, vif, config): + """Add a network interface. vif device index - vmac device MAC + config device configuration returns device """ - if vmac is None: - mac = self.randomMAC() - else: - mac = [ int(x, 16) for x in vmac.split(':') ] - if len(mac) != 6: raise ValueError("invalid mac") - dev = NetDev(self, vif, mac) + dev = NetDev(self, vif, config) self.devices[vif] = dev return dev @@ -259,14 +254,14 @@ class NetifController(controller.Controller): for dev in self.getDevices(): dev.destroy() - def attachDevice(self, vif, vmac, recreate=0): + def attachDevice(self, vif, config, recreate=0): """Attach a network device. If vmac is None a random mac address is assigned. @param vif interface index @param vmac mac address (string) """ - self.addDevice(vif, vmac) + self.addDevice(vif, config) d = defer.Deferred() if recreate: d.callback(self) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 223a9f5602..9e2975d24e 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -2,6 +2,7 @@ """Domain creation. """ +import random import string import sys @@ -127,11 +128,13 @@ gopts.var('ipaddr', val="IPADDR", fn=append_value, default=[], use="Add an IP address to the domain.") -gopts.var('vif', val="mac=MAC,bridge=BRIDGE", +gopts.var('vif', val="mac=MAC,bridge=BRIDGE,script=SCRIPT", fn=append_value, default=[], use="""Add a network interface with the given MAC address and bridge. + The vif is configured by calling the given configuration script. If mac is not specified a random MAC address is used. If bridge is not specified the default bridge is used. + If script is not specified the default script is used. This option may be repeated to add more than one vif. Specifying vifs will increase the number of interfaces as needed. """) @@ -227,6 +230,24 @@ def configure_pci(config_devs, vals): config_pci = ['pci', ['bus', bus], ['dev', dev], ['func', func]] config_devs.append(['device', config_pci]) +def randomMAC(): + """Generate a random MAC address. + + Uses OUI (Organizationally Unique Identifier) AA:00:00, an + unassigned one that used to belong to DEC. The OUI list is + available at 'standards.ieee.org'. + + The remaining 3 fields are random, with the first bit of the first + random field set 0. + + returns array of 6 ints + """ + mac = [ 0xaa, 0x00, 0x00, + random.randint(0x00, 0x7f), + random.randint(0x00, 0xff), + random.randint(0x00, 0xff) ] + return ':'.join(map(lambda x: "%x" % x, mac)) + def configure_vifs(config_devs, vals): """Create the config for virtual network interfaces. """ @@ -238,14 +259,17 @@ def configure_vifs(config_devs, vals): d = vifs[idx] mac = d.get('mac') bridge = d.get('bridge') + script = d.get('script') else: - mac = None + mac = randomMAC() bridge = None + script = None config_vif = ['vif'] - if mac: - config_vif.append(['mac', mac]) + config_vif.append(['mac', mac]) if bridge: config_vif.append(['bridge', bridge]) + if script: + config_vif.append(['script', script]) config_devs.append(['device', config_vif]) def configure_vfr(config, vals): -- 2.30.2